require 'fiddle'
require 'net/http'
require 'uri'
require 'time'
load 'facecat.rb'

$gPaint = FCPaint.new()
$gPaint.defaultUIStyle = "dark"

#面积图数据
class PyrometerData
	attr_accessor :value, :key, :lastClose, :close, :text, :type, :location, :size
	def initialize
		@value = 0.0 #数值
		@key = nil #键
		@lastClose = 0.0 #开始数据
		@close = 0.0 #最新数据
		@text = "" #数值
		@location = FCPoint.new(0, 0) #位置
		@size = FCSize.new(0, 0) #大小
	end
end

#面积图
class PyrometerDiv < FCView
	attr_accessor :useAnimation, :viewType, :INF, :Rwidth, :Rheight, :children, :rects
	def initialize
		super()
		@useAnimation = false #是否使用动画
		@viewType = "pyrometer" #类型
		@INF = 0x3f3f3f #无效数据
		@Rwidth = 0.0 #宽度
		@Rheight = 0.0 #高度
		@children = [] #子视图
		@rects = []
	end
end

#视图的鼠标按下方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
$gPaint.onPaint = Proc.new do|view, paint, clipRect|
	if view.viewType == "pyrometer"
		drawDiv(view, paint, clipRect)
		for i in 0..view.children.length - 1
			pData = view.children[i]
			backColor = "none"
			borderColor = "none"
			if view.paint.defaultUIStyle == "dark"
				if pData.close >= pData.lastClose
					backColor = "rgb(219,68,83)"
				else
					backColor = "rgb(15,193,118)"
				end
				borderColor = "rgb(0,0,0)"
			elsif view.paint.defaultUIStyle == "light"
				if pData.close >= pData.lastClose
					backColor = "rgb(255,255,255)"
				else
					backColor = "rgb(255,255,255)"
				end
				borderColor = "rgb(255,255,255)"
			end
			paint.fillRect(backColor, pData.location.x, pData.location.y, pData.location.x + pData.size.cx, pData.location.y + pData.size.cy)
			paint.drawRect(borderColor, 1, 0, pData.location.x, pData.location.y, pData.location.x + pData.size.cx, pData.location.y + pData.size.cy)
			fontSize1 = ([pData.size.cx, pData.size.cy].min / 5).to_i
			if fontSize1 > 1
				baseUpper = pData.text
				font1 = "Default," + fontSize1.to_s
				tSize = paint.textSize(baseUpper, font1)
				isContinue = false
				while tSize.cx > pData.size.cx - 10
					fontSize1 = fontSize1 - 1
					if fontSize1 < 1
						isContinue = true
						break
					end
					font1 = "Default," + fontSize1.to_s
					tSize = paint.textSize(baseUpper, font1)
				end   
				if isContinue
					next
				end
				quoteUpper = pData.key
				font2 = "Default," + (fontSize1 / 2).to_s
				tSize2 = paint.textSize(quoteUpper, font2)
				if view.paint.defaultUIStyle == "dark"
					paint.drawText(baseUpper, "rgb(255,255,255)", font1, pData.location.x + (pData.size.cx - tSize.cx) / 2, pData.location.y + pData.size.cy / 2 - tSize.cy - tSize.cy / 2)
					paint.drawText(quoteUpper, "rgb(255,255,255)", font2, pData.location.x + (pData.size.cx - tSize2.cx) / 2, pData.location.y + pData.size.cy / 2 - tSize.cy / 4)
				elsif view.paint.defaultUIStyle == "light"
					paint.drawText(baseUpper, "rgb(0,0,0)", font1, pData.location.x + (pData.size.cx - tSize.cx) / 2, pData.location.y + pData.size.cy / 2 - tSize.cy- tSize.cy / 2)
					paint.drawText(quoteUpper, "rgb(0,0,0)", font2, pData.location.x + (pData.size.cx - tSize2.cx) / 2, pData.location.y + pData.size.cy / 2- tSize.cy / 4)
				end
				strPrice = "0.00%"
				if pData.lastClose > 0
					strPrice = toFixed(100 * (pData.close - pData.lastClose) / pData.lastClose, 2) + "%"
					if pData.close > pData.lastClose
						strPrice = "+" + strPrice
					end
				end
				font3 = "Default," + (fontSize1 * 2 / 3).to_s
				tSize5 = paint.textSize(strPrice, font3)
				if view.paint.defaultUIStyle == "dark"
					paint.drawText(strPrice, "rgb(255,255,255)", font3, pData.location.x + (pData.size.cx - tSize5.cx) / 2, pData.location.y + pData.size.cy / 2 + tSize.cy- tSize.cy / 2)
				elsif view.paint.defaultUIStyle == "light"
					paint.drawText(strPrice, "rgb(0,0,0)", font3, pData.location.x + (pData.size.cx - tSize5.cx) / 2, pData.location.y + pData.size.cy / 2 + tSize.cy- tSize.cy / 2)
				end
			end
		end
	else
		onPaintDefault(view, paint, clipRect)
	end
end

#重置行
def layoutrow(pyrometer, rl, w)
	width = pyrometer.size.cx
	height = pyrometer.size.cy
	lx = width - pyrometer.Rwidth
	ly = height - pyrometer.Rheight
	direction = 0  
	sumValue = 0.0
	for x in 0..rl.length - 1
		sumValue = sumValue + rl[x]
	end
	ext = sumValue / w
	if (w - pyrometer.Rwidth).abs <= 1e-6
		pyrometer.Rheight = pyrometer.Rheight - ext
		direction = 0
	else
		pyrometer.Rwidth = pyrometer.Rwidth - ext
		direction = 1
	end
	for x in 0..rl.length - 1
		r = rl[x]
		if direction == 0
			hh = ext
			ww = r / ext
			newRect = FCRect.new(0, 0, 0, 0)
			newRect.left = lx.floor
			newRect.top = ly.floor
			newRect.right = (lx + ww).ceil
			newRect.bottom = (ly + hh).ceil
			pyrometer.rects.append(newRect)
			lx = lx + ww
		else
			ww = ext
			hh = r / ext
			newRect = FCRect.new(0, 0, 0, 0)
			newRect.left = lx.floor
			newRect.top = ly.floor
			newRect.right = (lx + ww).ceil
			newRect.bottom = (ly + hh).ceil
			pyrometer.rects.append(newRect)
			ly = ly + hh
		end
	end
end

#获取长度
def rWidth(pyrometer, rl, w)
	return [pyrometer.Rwidth, pyrometer.Rheight].min
end

#获取最差的值
def worst(pyrometer, rl, w)
	if rl.length == 0
		return pyrometer.INF
	end
	rmx = 0.0
	rmn = pyrometer.INF
	s = 0.0
	for x in 0..rl.length - 1
		r = rl[x]
		s = s + r
		if r > rmx
			rmx = r
		end
		if r < rmn
			rmn = r
		end
	end
	pw = w ** 2.0
	sw = s ** 2.0
	return [pw * rmx / sw, sw / (pw * rmn)].max
end

#秒表事件
#pyrometer 面积图
def onPyrometerTime(pyrometer)
	paint2 = false
	if pyrometer.useAnimation
		for i in 0..pyrometer.rects.length - 1
			subView = pyrometer.children[i]
			targetRect = pyrometer.rects[i]
			nowRect = FCRect.new(subView.location.x, subView.location.y, subView.location.x + subView.size.cx, subView.location.y + subView.size.cy)
			if 1 == 1
				if nowRect.left > targetRect.left
					nowRect.left -= (nowRect.left - targetRect.left) / 4
					if nowRect.left - targetRect.left < 10
						nowRect.left = targetRect.left
					end
					paint2 = true
				elsif nowRect.left < targetRect.left
					nowRect.left += (targetRect.left - nowRect.left) / 4
					if targetRect.left - nowRect.left < 10
						nowRect.left = targetRect.left
					end
					paint2 = true
				end
			end
			if 1 == 1
				if nowRect.top > targetRect.top
					nowRect.top -= (nowRect.top - targetRect.top) / 4
					if nowRect.top - targetRect.top < 10
						nowRect.top = targetRect.top
					end
					paint2 = true
				elsif nowRect.top < targetRect.top
					nowRect.top += (targetRect.top - nowRect.top) / 4
					if targetRect.top - nowRect.top < 10
						nowRect.top = targetRect.top
					end
					paint2 = true
				end
			end
			if 1 == 1
				if nowRect.right > targetRect.right
					nowRect.right -= (nowRect.right - targetRect.right) / 4
					if nowRect.right - targetRect.right < 10
						nowRect.right = targetRect.right
					end
					paint2 = true
				elsif nowRect.right < targetRect.right
					nowRect.right += (targetRect.right - nowRect.right) / 4
					if targetRect.right - nowRect.right < 10
						nowRect.right = targetRect.right
					end
					paint2 = true
				end
			end
			if 1 == 1
				if nowRect.bottom > targetRect.bottom
					nowRect.bottom -= (nowRect.bottom - targetRect.bottom) / 4
					if nowRect.bottom - targetRect.bottom < 10
						nowRect.bottom = targetRect.bottom
					end
					paint2 = true
				elsif nowRect.bottom < targetRect.bottom
					nowRect.bottom += (targetRect.bottom - nowRect.bottom) / 4
					if targetRect.bottom - nowRect.bottom < 10
						nowRect.bottom = targetRect.bottom
					end
					paint2 = true
				end
			end
			subView.location = FCPoint.new(nowRect.left, nowRect.top)
			subView.size = FCSize.new(nowRect.right - nowRect.left, nowRect.bottom - nowRect.top)
		end
	else
		for i in 0..pyrometer.rects.length - 1
			subView = pyrometer.children[i]
			targetRect = pyrometer.rects[i]
			subView.location = FCPoint.new(targetRect.left, targetRect.top)
			subView.size = FCSize.new(targetRect.right - targetRect.left, targetRect.bottom - targetRect.top)
		end
	end
	if paint2
		invalidateView(pyrometer)
	end
end

#更新面积图
#pyrometer 面积图
def updatePyromoter(pyrometer)
	pyrometer.rects = []
	totalAmount = 0.0
	for i in 0..pyrometer.children.length - 1
		totalAmount += pyrometer.children[i].value
	end
	rates = []
	for i in 0..pyrometer.children.length - 1
		rates.append(pyrometer.children[i].value / totalAmount)
	end
	pyrometer.Rwidth = pyrometer.size.cx
	pyrometer.Rheight = pyrometer.size.cy
	areas = []
	for i in 0..rates.length - 1
		areas.append(rates[i] * pyrometer.size.cx * pyrometer.size.cy)
	end
	children = areas
	row = []
	w = [pyrometer.Rwidth, pyrometer.Rheight].min
	while 1 == 1
		if pyrometer.rects.length > pyrometer.children.length
			break
		end
		if w <= 0
			break
		end
		if children.length == 0
			if row.length > 0
				layoutrow(pyrometer, row, w)  
			end
			break
		end
		c = children[0]
		if c == 0
			layoutrow(pyrometer, row, w)
			break
		end
		newrow = []
		for x in 0..row.length - 1
			newrow.append(row[x])
		end
		newrow.append(c)
		if worst(pyrometer, row, w) >= worst(pyrometer, newrow, w)
			tmp = []
			for x in 1..children.length - 1
				tmp.append(children[x])
			end
			children = tmp
			row = newrow
		else
			layoutrow(pyrometer, row, w)  
			row = []
			w = rWidth(pyrometer, row, w.to_i)
		end
	end
end

#更新悬浮状态
#views:视图集合
$gPaint.onUpdateView = Proc.new do|views|
	updateViewDefault(views)
	for i in 0..views.length - 1
		view = views[i]
		if view.viewType == "pyrometer"
			updatePyromoter(view)
			onPyrometerTime(view)
		end
	end
end

def queryPrice()
	url = "http://110.42.188.197:9968/quote?func=price&count=100&codes=all"
	uri = URI(url)
	response = Net::HTTP.get_response(uri)
	result = response.body
	dataList = []
	strs = result.split("\r\n")
	for i in 0..strs.length - 1
		subStrs = strs[i].split(",")
		if subStrs.length >= 15
			pData = PyrometerData.new()
			pData.key = subStrs[0]
			pData.text = subStrs[1]
			pData.value = subStrs[6].to_f
			pData.close = subStrs[2].to_f
			pData.lastClose = subStrs[8].to_f 
			pData.size = FCSize.new(0, 0)
			pData.location = FCPoint.new($pyrometer.size.cx, $pyrometer.size.cy)
			if pData.value > 0
				$pyrometer.children.append(pData)
			end
		end
	end
	$pyrometer.children = $pyrometer.children.sort_by { |e| -e.value }
	updateViewDefault($gPaint.views)
	updatePyromoter($pyrometer)
	onPyrometerTime($pyrometer)
	invalidateView($pyrometer)
end

WndProc = Fiddle::Closure::BlockCaller.new(Fiddle::TYPE_VOID, [Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT]) do |hWnd, message, wParam, lParam|
	WndProcDefault($gPaint, hWnd, message, wParam, lParam)	
end
$registerWndProc = Fiddle::Function.new(
  $facecat['registerWndProc'],
  [Fiddle::TYPE_VOIDP],
  Fiddle::TYPE_VOID
)
initWindow()
$registerWndProc.call(WndProc.to_i)
createWindow($gPaint)
#创建和添加视图
$pyrometer = PyrometerDiv.new()
#填充布局
$pyrometer.dock = "fill"
$pyrometer.backColor = "rgb(0,0,0)"
#添加到框架
addView($pyrometer, $gPaint)
queryPrice()
showWindow()

